#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <UIKit/UIApplication.h>
#import <LockInfo/Plugin.h>

#import "framework/FWCommon.h"
#import "framework/FWColorIconView.h"
#import "framework/FWPlugin.h"
#import "framework/FWMapView.h"

#import "PITaskListAccess.h"
#import "PITaskStatus.h"
#import "PITaskPlugin.h"
#import "PIPlugin.h"
#import "PITaskPreview.h"
#import "PIIntegration.h"
#import "PIContextObject.h"
#import "PITaskIntegration.h"
#import "PITaskNative.h"
#import "PITask.h"
#import "PIAlarm.h"


static NSString* const kNotesPageDetail = @"-1";
static NSString* const kLinkPageLookup = @"-2";
static NSString* const kTagsPageLookup = @"-3";
static NSString* const kNotesNumbersPage = @"-4";
static NSString* const kMapPage = @"-6";


@implementation PITaskPreview

@synthesize parentKeys, detailPageID, currentTask, currentApplication, controlDelegate;


- (id)initWithApplication:(FWApplication*)application
{
    if ((self = [super init])) {
        self.currentApplication = application;
        self.controlDelegate = nil;

        directPIAccess = ((PIPlugin*)application.fwPlugin).dbVersion >= PIDatabaseVersion250;
    }
    
    return self;
}

- (void)dealloc
{
    [parentKeys release];
    [detailPageID release];
    [currentTask release];
    [currentApplication release];
    
    [super dealloc];
}

- (PITask*)augmentTask:(PITask*)task application:(FWApplication*)application
{
    if (task.isNative)
        return [PITaskNative augmentedBasicTask:task application:application];
    else {
        FWDatabase* database = nil;
        @try {
            database = FWDBConnectDatabase(application.databasePath, application);
            return [PITaskIntegration augmentedBasicTask:task database:database application:application];
        }
        @finally {
            FWDBDisconnectDatabase(database);
        }
    }
}


// ******************************************************************************************
#pragma mark -
#pragma mark Handling user input

-(void)gotoTaskClicked:(UIBarButtonItem*)sender
{
    NSURL* url = currentTask.isNative 
    ? [PITaskNative urlForShowTask:currentTask application:currentApplication]
    : [PITaskIntegration urlForShowTask:currentTask application:currentApplication];
    
    XLog(@"LI:%@: URL to display task = %@", currentApplication.resourceName, url);
    
    if (url)
        [currentApplication.fwPlugin.liPlugin launchURL:url];
}

-(void)completeTaskClicked:(UIBarButtonItem*)sender
{
    if (!currentTask.isComplete) {
        NSBundle* bundle = [NSBundle bundleForClass:[self class]];
        
        BOOL success = currentTask.isNative
        ? [PITaskNative completeTask:currentTask application:currentApplication]
        : [PITaskIntegration completeTask:currentTask application:currentApplication];
        
        if (success) {
            //[controlDelegate removeItem];
            currentTask.completionDate = [NSDate date];
            [controlDelegate redisplayCurrentItem:YES];
            
            [controlDelegate displayPopup:localize(bundle, @"New Task/Complete/Success")];
            
            // A native task will generate its own notification
            if (!currentTask.isNative)
                [(PITaskPlugin*)currentApplication.fwPlugin triggerUnconditionalRefresh];
        }
        else
            [controlDelegate displayPopup:localize(bundle, @"New Task/Complete/Error")];
    }
}

- (NSArray*)toolbarForDetailListPage:(NSObject *)page key:(NSObject *)key application:(FWApplication *)application
{
    self.currentTask = nil;
    
    if (key && [(NSString*)key isEqualToString:kTagsPageLookup])
        return nil;
    else {
        PITask* task = (PITask*)page;
        
        self.currentTask = task;
        NSBundle* bundle = [NSBundle bundleForClass:[self class]];
        
        UIBarButtonItem* completeBtn = [[[UIBarButtonItem alloc] initWithImage:
                                         [UIImage imageWithContentsOfFile:
                                          [application.applicationPath stringByAppendingString:@"/Completed.png"]]
                                                                         style:UIBarButtonItemStylePlain
                                                                        target:self
                                                                        action:@selector(completeTaskClicked:)] autorelease];
        completeBtn.enabled = !task.isComplete;
        
        UIBarButtonItem* flexBtn = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                                                                  target:nil
                                                                                  action:nil] autorelease];
        
        if (task.isNative) {
            UIBarButtonItem* gotoNativeBtn = [[[UIBarButtonItem alloc] initWithImage:
                                               [UIImage imageWithContentsOfFile:[bundle pathForResource:@"gonative"
                                                                                                 ofType:@"png"]]
                                                                               style:UIBarButtonItemStylePlain
                                                                              target:self
                                                                              action:@selector(gotoTaskClicked:)] autorelease];

            return [NSMutableArray arrayWithObjects:
                    flexBtn, completeBtn,
                    flexBtn, gotoNativeBtn,
                    flexBtn,
                    nil];
        }
        else {
            if (directPIAccess) {
                UIBarButtonItem* gotoPIBtn = [[[UIBarButtonItem alloc] initWithImage:
                                               [UIImage imageWithContentsOfFile:[bundle pathForResource:@"gopi"
                                                                                                 ofType:@"png"]]
                                                                               style:UIBarButtonItemStylePlain
                                                                              target:self
                                                                              action:@selector(gotoTaskClicked:)] autorelease];
                
                return [NSMutableArray arrayWithObjects:
                        flexBtn, completeBtn,
                        flexBtn, gotoPIBtn,
                        flexBtn,
                        nil];
            }
        }
    }
    
    return nil;
}

- (BOOL)doneClicked:(FWApplication*)application sections:(NSArray*)sections
{
    return YES;
}

- (FWDetailListEntry*)flaggedEntryWithTitle:(NSString*)title icon:(NSString*)icon calendarIcon:(NSString*)calendartIcon flagged:(BOOL)flagged largeFlag:(BOOL)large application:(FWApplication*)application
{
    FWDetailListEntry* titleEntry = [FWDetailListEntry entryWithTitle:[PIIntegration stringForTitle:title
                                                                                           withIcon:icon
                                                                                    withProjectIcon:calendartIcon
                                                                                         emojiAfter:((PITaskStatus*)application.info).emojiAfter]];
    if (flagged) {
        if (large)
            titleEntry.icon = [UIImage imageWithContentsOfFile:[PIIntegration iconPathForLargeFlag:application]];
        else
            titleEntry.icon = [UIImage imageWithContentsOfFile:[PIIntegration iconPathForSmallFlag:application]];
    }
    
    return titleEntry;
}


// ******************************************************************************************
#pragma mark -
#pragma mark Accessing records from the database

- (NSString*)captionForListPage:(NSObject*)page forKey:(NSObject*)key displayDepth:(NSInteger)depth application:(FWApplication *)application
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    
    if ([(NSString*)key isEqualToString:kNotesPageDetail])
        return localize(bundle, @"Detail/Notes");
    else if ([(NSString*)key isEqualToString:kTagsPageLookup])
        return localize(bundle, @"Detail/Tags");
    else if ([(NSString*)key isEqualToString:kNotesNumbersPage])
        return localize(bundle, @"Detail/Dialer/Title");
    else if ([(NSString*)key isEqualToString:kMapPage])
        return localize(bundle, @"Detail/Map");
    
    PITask* element = (PITask*)[(NSArray*)page objectAtIndex:0];
    if (element.isChild)
        return localize(bundle, @"Detail/Child");
    else if (element.isParent)
        return localize(bundle, @"Detail/Parent");
    else
        return @"";
}

- (NSArray*)dataForTagsListPage:(NSObject*)page application:(FWApplication *)application
{
    BOOL emojiAfter = ((PITaskStatus*)application.info).emojiAfter;
    
    PITask* task = [self augmentTask:(PITask*)page application:application];
    
    NSMutableArray* tagEntries = [NSMutableArray arrayWithCapacity:task.tags.count];
    NSMutableArray* tags = [NSMutableArray arrayWithArray:task.tags];
    [tags sortUsingFunction:compareContextObjectNames context:nil];
    
    for (PIContextObject* tag in tags) {
        [tagEntries addObject:
         [super detailColourEntryForTitle:tag.name
                                    value:nil
                                     icon:tag.icon
                             calendarIcon:nil
                            calendarColor:tag.color
                               emojiAfter:YES]];         
    }
    
    return [NSArray arrayWithObject:[FWDetailListSection sectionForElements:tagEntries]];
}


- (NSArray*)dataForTaskListPage:(NSObject*)page application:(FWApplication *)application
{
    FWDatabase* database = nil;
    @try {
        PITask* task = (PITask*)page;

        if (!task.isNative)
            database = FWDBConnectDatabase(application.databasePath, application);
        
        NSBundle* bundle = [NSBundle bundleForClass:[self class]];
        task = task.isNative ? [PITaskNative augmentedBasicTask:task application:application] : [PITaskIntegration augmentedBasicTask:task database:database application:application];
        
        XLog(@"LI:PITask: Displaying detail of task %@", task);
        
        FWDetailListEntry* titleRows = [[self flaggedEntryWithTitle:task.title
                                                               icon:task.icon
                                                       calendarIcon:nil
                                                            flagged:task.flagged
                                                          largeFlag:YES
                                                        application:application]
                                        withSize:[FWDetailListEntry fontSizeForTitle]];
        
        NSMutableArray* titleSect = [NSMutableArray arrayWithCapacity:5];
        [titleSect addObject:titleRows];
        
        if (task.locations.count > 0) {
            PILocation* loc = [task.locations objectAtIndex:0];
            FWDetailListEntry* locationEntry = [FWDetailListEntry entryWithTitle:loc.title];
            
            if (loc.coordinates || (loc.title.length < 80)) {
                locationEntry.link = YES;
                locationEntry.key = kMapPage;
                locationEntry.icon = [UIImage imageWithContentsOfFile:[bundle pathForResource:@"map" ofType:@"png"]];
            }
            
            [titleSect addObject:locationEntry];
        }

        
        BOOL overdue = NO;
        UIColor* dateBG = [UIColor whiteColor];
        NSDate* startDate = task.startDate;
        NSDate* dueDate = task.dueDate;
        
        if (!dueDate.isNull) {
            NSDate *now = [NSDate date];
            if ([dueDate isEarlierThanDate:now]) {
                overdue = YES;
                dateBG = [PIIntegration colorForOverdue:application];
            }
        }
        
        // Dates section
        NSMutableArray* datesSect = [NSMutableArray arrayWithCapacity:2];
        NSMutableArray* debugDatesSect = [NSMutableArray arrayWithCapacity:5];
        
        if (!startDate.isNull) {
            BOOL showTime = task.hasStartTime;
            [datesSect addObject:
             [[FWDetailListEntry entryWithLocalisedTitle:@"Detail/Start"
                                                   value:FWTimeZoneDateStringForUTCDate(startDate, task.startDateTimeZone, FWDateFormatterLongFormat, showTime, bundle)
                                                  bundle:bundle]
              withBackgroundColor:dateBG]];
            
            if (application.fwPlugin.isDebugMode)
                [debugDatesSect addObject:
                 [[FWDetailListEntry entryWithTitle:@"Starts"
                                              value:[startDate description]] withClearBackground]];
        }
        if (application.fwPlugin.isDebugMode) {
            [debugDatesSect addObject:
             [[FWDetailListEntry entryWithTitle:@"-STZone"
                                          value:[task.startDateTimeZone description]] withClearBackground]];
            [debugDatesSect addObject:
             [[FWDetailListEntry entryWithTitle:@"-SRaw"
                                          value:[[NSDate dateWithTimeIntervalSinceReferenceDate:task.startDateRaw] description]]
             withClearBackground]];
        }
        
        if (!dueDate.isNull) {
            BOOL showTime = !task.isAllDay;
            [datesSect addObject:
             [[FWDetailListEntry entryWithLocalisedTitle:@"Detail/Due"
                                                   value:FWTimeZoneDateStringForUTCDate(dueDate, task.dueDateTimeZone, FWDateFormatterLongFormat, showTime, bundle)
                                                  bundle:bundle]
              withBackgroundColor:dateBG]];
            
            if (application.fwPlugin.isDebugMode)
                [debugDatesSect addObject:
                 [[FWDetailListEntry entryWithTitle:@"Due"
                                              value:[dueDate description]] withClearBackground]];
        }
        if (application.fwPlugin.isDebugMode) {
            [debugDatesSect addObject:
             [[FWDetailListEntry entryWithTitle:@"-DTZone"
                                          value:[task.dueDateTimeZone description]] withClearBackground]];
            [debugDatesSect addObject:
             [[FWDetailListEntry entryWithTitle:@"-DRaw"
                                          value:[[NSDate dateWithTimeIntervalSinceReferenceDate:task.dueDateRaw] description]]
             withClearBackground]];
        }
        
        // Context section
        NSMutableArray* contextSect = [NSMutableArray arrayWithCapacity:3];
#ifdef DEVELOPMENT_MODE
        [contextSect addObject:
         [FWDetailListEntry entryWithTitle:@"Key"
                                     value:task.key]];
#endif
        
        if ([task.context length] > 0)
            [contextSect addObject:
             [FWDetailListEntry entryWithLocalisedTitle:@"Detail/Context"
                                                  value:task.context
                                                 bundle:bundle]];
        
        if ([task.project length] > 0) {
            NSString* label = (task.priority.length == 0) && ([PIIntegration taskMode:application] == PITaskModeGTD) ? @"Detail/Project" : @"Detail/Folder";
            [contextSect addObject:
             [FWDetailListEntry entryWithLocalisedTitle:label
                                                  value:task.project
                                                 bundle:bundle]];
        }
        
        if (task.tags) {
            FWDetailListEntry* entry = [FWDetailListEntry entryWithLocalisedTitle:@"Detail/Tags"
                                                                            value:[task.tags piContextObjectString]
                                                                           bundle:bundle];
            
            if (task.tags.count > 1)
                [entry withLinkType:kTagsPageLookup];
            
            [contextSect addObject:entry];
        }
        
        
        //    if (cCalendarID == -2)
        //        calendar = localize(bundle, @"Detail/Internal Task Calendar");
        if (task.calendar) {
            [contextSect addObject:
             [super detailColourEntryForTitle:localize(bundle, task.isNative ? @"Detail/Calendar/iOS" : @"Detail/Calendar/PI")
                                        value:FWSplittableString(task.calendar)
                                         icon:nil
                                 calendarIcon:task.calendarIcon
                                calendarColor:task.calendarColor
                                   emojiAfter:((PITaskStatus*)application.info).emojiAfter]];
        }
        
        // Progress section
        NSMutableArray* progressSect = [NSMutableArray arrayWithCapacity:4];
        if (task.isComplete) {
            [progressSect addObject:
             [FWDetailListEntry entryWithLocalisedTitle:@"Detail/Action"
                                         localisedValue:@"Complete"
                                                 bundle:bundle]];
        }
        else {
            FWColorIconView* progressIcon = [[[FWColorIconView alloc] initWithFrame:CGRectMake(0, 0,  16, 16)] autorelease];
            progressIcon.icon = [PIIntegration iconPathForAction:task.action application:application];
            if (progressIcon.icon) {
                [progressSect addObject:
                 [[FWDetailListEntry entryWithLocalisedTitle:@"Detail/Action"
                                              localisedValue:[PIIntegration nameForAction:task.action]
                                                      bundle:bundle]
                  withColorAccessoryView:progressIcon]];
            }
        }
        
        NSString* importance = localize(bundle, [PIIntegration nameForImportance:task.importance]);
        if ([task.priority length] > 0) {
            NSString* priority = [NSString stringWithFormat:@"%@\n%@", task.priority, importance];
            NSString* title = [NSString stringWithFormat:@"%@\n%@",
                               localize(bundle, @"Detail/Priority"),
                               localize(bundle, @"Detail/Importance")];
            
            [progressSect addObject:
             [[super detailColourEntryForTitle:title
                                         value:priority
                                          icon:nil
                                  calendarIcon:nil
                                 calendarColor:[PIIntegration colorBGForImportance:task.importance application:application]
                                    emojiAfter:((PITaskStatus*)application.info).emojiAfter]
              withLines:2]];
        }
        else {
            [progressSect addObject:
             [super detailColourEntryForTitle:localize(bundle, @"Detail/Importance")
                                        value:importance
                                         icon:nil
                                 calendarIcon:nil
                                calendarColor:[PIIntegration colorBGForImportance:task.importance application:application]
                                   emojiAfter:((PITaskStatus*)application.info).emojiAfter]];
        }
        
        if (!task.isNative) {
            NSInteger percentComplete = task.isComplete ? 100 : task.percentComplete;
            [progressSect addObject:
             [[FWDetailListEntry entryWithTitle:[NSString stringWithFormat:localize(bundle, @"Detail/Complete"), percentComplete]
                                          value:[NSNumber numberWithFloat:(percentComplete / 100.0)]]
              withProgressType]];
        }
        
        // Repeat info
        NSArray* repeatSect = [super repeatSectionForObject:task bundle:bundle application:application];
        
        NSMutableArray* sensitivitySect = [NSMutableArray arrayWithCapacity:1];
        if (task.sensitivity != PISensitivityTypeNone)
            [sensitivitySect addObject:[self entryForSensitivity:task.sensitivity bundle:bundle]];

        // Notes section
        NSMutableArray* notesSect = [NSMutableArray arrayWithCapacity:2];
        if (NSString* notes = task.notesSummary) {
            if ([[notes stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] > 0) {
                if (notes.length != task.notes.length) {
                    [notesSect addObject:
                     [[[FWDetailListEntry entryWithTitle:notes]
                       withSize:[UIFont systemFontSize]]
                      withNoBold]];
                    [notesSect addObject:
                     [[[FWDetailListEntry entryWithLocalisedTitle:@"Detail/Show Notes"
#ifdef DEVELOPMENT_MODE
                                                            value:kNotesPageDetail
#endif
                                                           bundle:bundle]
                       withIconFile:[bundle pathForResource:@"notes" ofType:@"png"]]
                      withLinkType:kNotesPageDetail]];
                }
                else {
                    [notesSect addObject:
                     [[[FWDetailListEntry entryWithTitle:notes]
                       withSize:[UIFont systemFontSize]]
                      withNoBold]];
                }
                
                NSString* platform = FWGetPlatformType();
                BOOL hasRadio = platform && [platform isEqualToString:@"iPhone"];
                
#ifdef DEVELOPMENT_MODE
                hasRadio = YES;
#endif
                
                if (hasRadio && [self numbersFromString:task.notes])
                    [notesSect addObject:
                     [[[FWDetailListEntry entryWithLocalisedTitle:@"Detail/Numbers"
#ifdef DEVELOPMENT_MODE
                                                            value:kNotesNumbersPage
#endif
                                                           bundle:bundle]
                       withIconFile:[bundle pathForResource:@"phone" ofType:@"png"]]
                      withLinkType:kNotesNumbersPage]];
            }    
        }     

        // Alarms section
        NSArray* alarmsSect = [super alarmsListForObject:task dueDate:task.dueDate bundle:bundle application:application];
        
        // Children/parent section
        FWDetailListSection* relationsSect = nil;
        if (task.isParent) {
            // Fetch child elements
            NSArray* children = [PITaskIntegration basicTaskList:application
                                                        database:database prefs:nil key:nil parentKey:task.key search:nil];
            if ([children count] > 0) {
                NSMutableArray* childs = [NSMutableArray arrayWithCapacity:children.count];
                for (PITask* child in children) {
                    [childs addObject:[[[self flaggedEntryWithTitle:child.title
                                                               icon:child.icon
                                                       calendarIcon:child.calendarIcon
                                                            flagged:child.flagged
                                                          largeFlag:NO
                                                        application:application]
#ifdef DEBUG_STATUS
                                        withValue:child.key]
#else
                                       withValue:nil]
#endif
                         withLinkType:child.key]];
                }
                relationsSect = [FWDetailListSection sectionForElements:childs withTitle:localize(bundle, @"Detail/Children")];
            }
        }
        else if (task.isChild && task.parentKey) {
            // Fetch parent element
            NSArray* parents = [PITaskIntegration basicTaskList:application
                                                       database:database prefs:nil key:task.parentKey parentKey:nil search:nil];
            if ([parents count] > 0) {
                PITask* parent = [parents objectAtIndex:0];
                FWDetailListEntry* link = [[[self flaggedEntryWithTitle:parent.title
                                                                   icon:parent.icon
                                                           calendarIcon:parent.calendarIcon
                                                                flagged:parent.flagged
                                                              largeFlag:NO
                                                            application:application]
#ifdef DEBUG_STATUS
                                            withValue:parent.key]
#else
                                           withValue:nil]
#endif
            withLinkType:parent.key];
                relationsSect = [FWDetailListSection sectionForElements:[NSArray arrayWithObject:link] 
                                                              withTitle:localize(bundle, @"Detail/Parent")];
            }
        }
        
        // Build sections list
        NSMutableArray* sects = [NSMutableArray arrayWithCapacity:6];
        [sects addObject:[[FWDetailListSection sectionForElements:titleSect]
                          withExtraSeparatorSpace:kFWDetailListViewExtraHeaderSpace]];
        if ([datesSect count] > 0)
            [sects addObject:[FWDetailListSection sectionForElements:datesSect]];
        if ([progressSect count] > 0)
            [sects addObject:[FWDetailListSection sectionForElements:progressSect]];
        if ([sensitivitySect count] > 0)
            [sects addObject:[FWDetailListSection sectionForElements:sensitivitySect]];
        if ([contextSect count] > 0)
            [sects addObject:[FWDetailListSection sectionForElements:contextSect]];
        if ([repeatSect count] > 0)
            [sects addObject:[FWDetailListSection sectionForElements:repeatSect]];
        if ([alarmsSect count] > 0)
            [sects addObject:[FWDetailListSection sectionForElements:alarmsSect]];
        if (relationsSect)
            [sects addObject:relationsSect];
        if ([notesSect count] > 0)
            [sects addObject:[FWDetailListSection sectionForElements:notesSect
                                                           withTitle:localize(bundle, @"Detail/Notes")]];
        if ([debugDatesSect count] > 0)
            [sects addObject:[FWDetailListSection sectionForElements:debugDatesSect withTitle:@"Task Date Values"]];
        
        if (parentKeys) {
            for (FWDetailListSection* sect in sects) {
                for (FWDetailListEntry* element in sect.entries) {
                    if (element.isLink) {
                        for (NSString* key in parentKeys) {
                            if ([element.key isEqualToString:key]) {
                                element.link = NO;
                                element.backLink = YES;
                                break;
                            }
                        }
                    }
                }
            }
        }
        
        return sects;
    }
    @finally {
        FWDBDisconnectDatabase(database);
    }
}

- (NSArray*)dataForDetailListPage:(NSObject*)page key:(NSObject*)key application:(FWApplication *)application
{
    if (key && [(NSString*)key isEqualToString:kTagsPageLookup])
        return [self dataForTagsListPage:page application:application];
    else if (key && [(NSString*)key isEqualToString:kNotesNumbersPage]) {
        PITask* augment = [self augmentTask:(PITask*)page application:application];
        return [self dataForNumberListPage:(PITask*)page application:application string:augment.notes prompt:nil];
    }
    else
        return [self dataForTaskListPage:page application:application];
}

- (void)willShowBasePage:(NSObject*)page
{
    self.parentKeys = nil;
    self.detailPageID = nil;
}

- (NSString*)listPageTextForKey:(NSObject *)key currentPage:(NSObject *)page displayDepth:(NSInteger)depth application:(FWApplication *)application
{
    if ([(NSString*)key isEqualToString:kNotesPageDetail]) {
        PITask* task = [self augmentTask:(PITask*)page application:application];
        if (task.notes)
            return task.notes;
        else
            return @"";
    }
    
    return nil;
}

- (NSArray*)listPageInfoForKey:(NSObject*)key currentPage:(NSObject*)current displayDepth:(NSInteger)depth application:(FWApplication *)application
{
    self.detailPageID = (NSString*)key;
    
    if ([(NSString*)key isEqualToString:kTagsPageLookup])
        return [NSArray arrayWithObject:current];
    else if ([(NSString*)key isEqualToString:kNotesNumbersPage])
        return [NSArray arrayWithObject:current];
    
    if (depth >= 1) {
        if (!parentKeys)
            self.parentKeys = [NSMutableArray arrayWithCapacity:3];
        
        while (parentKeys.count >= depth)
            [parentKeys removeLastObject];
        
        [parentKeys addObject:((PITask*)current).key];
    }
    
    FWDatabase* database = nil;
    @try {
        database = FWDBConnectDatabase(application.databasePath, application);
        return [PITaskIntegration basicTaskList:application database:database prefs:nil key:(NSString*)key parentKey:nil search:nil];
    }
    @finally {
        FWDBDisconnectDatabase(database);
    }
}


// ******************************************************************************************
#pragma mark -
#pragma mark Map page support

- (UIView*)listPageViewForKey:(NSObject *)key currentPage:(NSObject *)page displayDepth:(NSInteger)depth rect:(CGRect)rect application:(FWApplication *)application
{
    if ([(NSString*)key hasPrefix:kPIPreviewAlarmsPageLookup]) {

        PITask* task = [self augmentTask:(PITask*)page application:application];
        
        NSInteger index = [[(NSString*)key substringFromIndex:[kPIPreviewAlarmsPageLookup length]] intValue];
        PIAlarm* alarm = [task.alarms objectAtIndex:index];

        FWMapView* view = [[[FWMapView alloc] initWithFrame:rect
                                                     config:application.info
                                                     plugin:application.fwPlugin.liPlugin
                                                 showPopups:YES
                                                   location:alarm.location
                                                      title:task.title
                                                coordinates:alarm.coordinates] autorelease];
        return view;
    }

    if ([(NSString*)key isEqualToString:kMapPage]) {
        
        PITask* task = [self augmentTask:(PITask*)page application:application];

        PILocation* loc = [task.locations objectAtIndex:0];
        FWMapView* view = [[[FWMapView alloc] initWithFrame:rect
                                                     config:application.info
                                                     plugin:application.fwPlugin.liPlugin
                                                 showPopups:YES
                                                   location:loc.title
                                                      title:task.title
                                                coordinates:loc.coordinates] autorelease];
        return view;
    }
    
    return nil;
}

@end
